במקום לכתוב רשימה שלמה של אינקלודים בתחילת כל סקריפט כשחצי מהם יכולים בכלל לא להידרש נדאג לטעון רק את הפונקציות שצריך ורק כשצריך אותם בשיטת LazyLoad
כתבתם מחלקה לעבודה עם מסד נתונים ואתם עושים לה include בסקריפט שלכם. אבל לפעמים הסקריפט לא באמת צריך להתחבר למסד (למשל לא מילאו את כל השדות של הטופס).
אפשר להכניס את ה-include לתוך התנאי ולבצע אותו רק אם כל הטופס מלא, אבל כשהסקריפטים הופכים לארוכים עם עשרות מקרים ואף יותר תנאים כאלה ואחרים כבר קשה לזכור איפה צריך חיבור, האם כבר עשינו חיבור ומה לא.
autoload היא פונקציה ש-php מבצעת ברגע שאנחנו מנסים להשתמש במחלקה שעדיין לא הוגדרה.
spl_autoload_register
spl_autoload_register הופכת את הפונקציה שנומר לה לפונקציה שלה php תקרא כל פעם שתתקל במחלקה לא ידוע עד כה.
function this_function_will_be_called_every_time_we_call_unregistered_class($name)
{
echo 'php is trying to use class "', $name, '"<br/>';
return true;
}
spl_autoload_register('this_function_will_be_called_every_time_we_call_unregistered_class');
$x = new myphpclass(); // myphpclass does not exist
// therefore our function will be called
{
echo 'php is trying to use class "', $name, '"<br/>';
return true;
}
spl_autoload_register('this_function_will_be_called_every_time_we_call_unregistered_class');
$x = new myphpclass(); // myphpclass does not exist
// therefore our function will be called
הריצו את הקוד הבא ותקבלו הודעה
php is trying to use class myphpclass
שם המחלקה ש-php ניסתה למצוא מועבר כפרמטר לפונקציה שלנו.
במקרה הזה גם קיבלתם שגיאה Fatal error: Class 'myphpclass' not found , כיוון ש-php בכל זאת לא מצאה את החלקה שחיפשה.
במידה וננסה להשתמש במחלקה ש-php כבר מכירה, הפונקציה הזו לא תתבצע:
<?php
/** Some example class */
class mydb
{
/** Examples constructor */
public function __construct()
{
echo 'new mydb instance created';
}
}
/**
* Autoload function, called when php is looking for not defined class
* @param string $name the name of the class php is looking for
*/
function autoload($name)
{
echo 'php is trying to use class ', $name, '<br/>';
}
// Make the function to be autoload
spl_autoload_register('autoload');
// Use the mydb class
$y = new mydb();
/** Some example class */
class mydb
{
/** Examples constructor */
public function __construct()
{
echo 'new mydb instance created';
}
}
/**
* Autoload function, called when php is looking for not defined class
* @param string $name the name of the class php is looking for
*/
function autoload($name)
{
echo 'php is trying to use class ', $name, '<br/>';
}
// Make the function to be autoload
spl_autoload_register('autoload');
// Use the mydb class
$y = new mydb();
שימו לב שהפעם הפונקציה 'autoload' לא התבצעה, כיוון ש-php כבר הכירה את המחלקה mydb
טעינה של מחלקה
השם של המחלקה ש php מחפשת מגיע בתור פרמטר לפונקציה autoload.
נוכל להשתמש בשם שלה כדי לעשות include לקובץ שמכיל את המחלקה.
נניח שהמחלקה mydb מוגדרת בקובץ mydb.php בתיקיה classes
/**
* Autoload function, called when php is looking for not defined class
* @param string $name the name of the class php is looking for
*/
function autoload($name)
{
echo 'including classes/'.$name.'.php';
require 'classes/'.$name.'.php';
}
// Make the function to be autoload
spl_autoload_register('autoload');
// Use the mydb class
$y = new mydb();
* Autoload function, called when php is looking for not defined class
* @param string $name the name of the class php is looking for
*/
function autoload($name)
{
echo 'including classes/'.$name.'.php';
require 'classes/'.$name.'.php';
}
// Make the function to be autoload
spl_autoload_register('autoload');
// Use the mydb class
$y = new mydb();
בקוד הזה ברגע ש-php תיתקל בשימוש במחלקה mydb היא תפעיל את הפונקציה autoload שתנסה לטעון את הקובץ mydb.php והסקריפט ימשיך לעבוד כמו שצריך.
הרבה אינקלודים בתחילת כל סקריפט
אם הסקריפט שלכם משתמש בהרבה מחלקות שונות, כנראה שבתחילת כל סקריפט אתם שמים הרבה מאוד אינקלודים. את כל האינקלודים האלה אפשר להחליף בפונקציית autoload אחת.
כמובן שגם אותה לא צריך להעתיק מסקריפט לסקריפט, אלה לשים בקובץ נפרד (עדיף בקובץ שבו יש הגדרות התחברות למסד, או כל קובץ אחר שגם ככה עושים לו אינקלוד בכל עמוד)
autoload בלי פונקציה
רק php > 5.3
בגרסאות החדשות יותר של php אפילו אין צורך לממש פונקציית autoload משלנו.
הקוד הבא ינסה לעשות include לקובץ mydb.php באותה תיקיה.
spl_autoload_extensions('.php');
spl_autoload_register();
$x = new mydb();
spl_autoload_register();
$x = new mydb();
הפונקציה הראשונה אומרת ל-php מה הסיומות האפשריות של הקבצים של המחלקות.
הפונקציה השניה בלי פרמטרים שוות ערך ל
require "$name.$ext";
כש-name זה שם המחלקה ש-php מנסה לטעון (mydb) ו-ext זה הסיומת שהפונקציה הראשונה הגדירה (.php). בפועל אפשר אפילו לוותר על הפונקציה הראשונה, כיוון שהסיומת .php כבר מוגדרת כברירת מחדל.
שני בעיות נוצרות בשימוש כזה בלי פונקציית autoload מוגדרת:
א. כל הקבצים חייבים להימצא באותה תיקייה.
ב. הפונקציה תנסה לקרוא לקובץ ששמו באותיות קטנות, גם אם השם של המחלקה מכיל אותיות גדולות. די קריטי עבור כל שרתי ה-linux שמבחינתם אלו קבצים שונים.
לכן כנראה שתעדיפו לכתוב פונקציית autoload משלכם, כמו זאתי שמובאת כאן בדוגמאות.
תגובות לכתבה:
עזר לי מאוד, תודה רבה אלכס :)
למה אתה משתמש בspl_autoload ולא במובנה: __autoload
http://www.php.net/autoload
בגלל שאם spl_autoload אני יכול לרשום מטודה של מחלקה בתור הלואדר
ולא סתם פונקציה שאמורה להיות זרוקה איפשהו